# You may, but are NOT required to, use object-oriented programming (OOP) in your solution.
# If you choose to use OOP, the methods described below should be class instance methods.

# You may put any variables that you wish to maintain at the module level:

hunting_threshold = 0.50  # Example optional module variable

# Other auxiliary functions are allowed, but your script must implement at least the three
# functions below, no matter what approach you choose to use. For the OOP option, don't
# forget to add 'self' as a first argument of every function.

def hunt_choices(round_number, current_food, current_reputation, m,  player_reputations):
    # The main routine that plays each individual round.

    # You must create an array of variables 'hunt_decisions' and assign an 'h' for hunt or
    # an 's' for slack (i.e., not hunt) to each member of the array; the order of the hunt
    # decisions in hunt_decisions should correspond to the order of opponents'
    # reputations in player_reputations.

    # Blank variables or errors will be assigned 's'.

    # The variables passed in to hunt_choices for your use are:
    #     round_number: integer, the number round you are in.
    #     current_food: integer, the amount of food you have.
    #     current_reputation: float (python's representation of real numbers), your current reputation.
    #     m: integer, the threshold cooperation/hunting value for this round.
    #     player_reputations: list of floats, the reputations of all the remaining players in the game.
    #                         The ordinal positions of players in this list will be randomized each round.

    # You may use the global syntax to assign values to any global variables you define, as in:

    """

    :param round_number:
    :param current_food:
    :param current_reputation:
    :param m:
    :param player_reputations:
    :return:
    """

    # Copy player_reputations into a new list ordered_player_reputations that we will sort.
    ordered_player_reputations = list(player_reputations)

    #print("\nplayer_reputations id: ")
    #print(id(player_reputations))

    #print("\nordered_player_reputations id:")
    #print(id(ordered_player_reputations))

    # Print un-sorted ordered_player_reputations
    #print ("\n")
    #print (ordered_player_reputations)

    # Sort ordered_player_reputations
    ordered_player_reputations.sort()

    # Print sorted ordered_player_reputations
    #print ("\n")
    #print (ordered_player_reputations)

    # Create dictionary of {reputation,percentile}
    reputation_percentile_dict = {}

    # Go through each item in the ordered_player_reputations list and update the dictionary with
    # the appropriate reputation,percentile pair.

    player_percentile = 0.0
    player_reputation_rank = 1.0

    for reputation in ordered_player_reputations:
        #print(player_reputation_rank)
        #print(reputation)
        # Compute the percentile for each given reputation.
        player_percentile = player_reputation_rank/len(ordered_player_reputations)
        #print(player_percentile)

        # Update dictionary with reputation , percentile pair.  If multiple player_reputations, then the higher percent
        # will be entered into the dictionary.
        reputation_percentile_dict[reputation] = player_percentile

        # Increment player_reputation_rank by 1.
        player_reputation_rank += 1

    # Print the full dictionary of reputation, player_percentile pairs:
    #print("Dictionary of {reputation,player_percentile}:\n")
    #print(reputation_percentile_dict)

    # For each reputation in player_reputations, determine if the according percentile is greater than or equal to the
    # threshold.  If it is, then hunt with that reputation, if it is not then slack with that reputation.

    global hunting_threshold

    hunt_decisions = list()

    for rep in player_reputations:
        if reputation_percentile_dict[rep] >= hunting_threshold:
            hunt_decisions.append('h')
        else:
            hunt_decisions.append('s')

    #print(player_reputations)

    #print(hunt_decisions)

    return hunt_decisions


def hunt_outcomes(food_earnings):
    # hunt_outcomes is called after all hunts for the round are complete.

    # Add any code you wish to modify your variables based on the outcome of the last round.

    # The variable passed in to hunt_outcomes for your use is:
    #     food_earnings: list of integers, the amount of food earned from the last round's hunts.
    #                    The entries can be negative as it is possible to lose food from a hunt.
    #                    The amount of food you have for the next round will be current_food
    #                    + sum of all entries of food_earnings + award from round_end.
    #                    The list will be in the same order as the decisions you made in that round.

    #print("####################### BEGIN HUNT OUTCOMES #######################")

    #print("FOOD EARNINGS:")
    #print (food_earnings)
    #print("\n")

    global hunting_threshold

    #print("Hunting Threshold Before: ")
    #print(hunting_threshold)
    #print("\n")

    # We want to modify the our hunting threshold based on the outcomes of hunt.
    # If we Hunt and they Hunted - then do nothing. (0 food)
    # If we Hunt and they Slack - Increase the threshold (-3 food)
    # If we slack and they slack - then do nothing (-2 food)
    # If we slack and they hunt - then decrease our threshold (+1 food)

    for food in food_earnings:
        if food == 0:
            pass
        elif food == -2:
            pass
        elif food == -3:
            hunting_threshold = hunting_threshold + (1.0/len(food_earnings))
        elif food == 1:
            hunting_threshold = hunting_threshold - (1.0/len(food_earnings))
        else:
            pass

        #print("hunting_threshold:")
        #print(hunting_threshold)

    #print("\n")
    #print("Hunting Threshold After: ")


    #print("####################### END HUNT OUTCOMES #######################")


def round_end(award, m, number_hunters):
    # round_end is called after all hunts for the round are complete.

    # award - the total amount of food you received due to cooperation in the round.
    # Can be zero if the threshold m was not reached.

    # Add any code you wish to modify your variables based on the cooperation that occurred in
    # the last round.

    # The variables passed in to round_end for your use are:
    #     award: integer, total food bonus (can be zero) you received due to players cooperating
    #            during the last round. The amount of food you have for the next round will be
    #            current_food (including food_earnings from hunt_outcomes this round) + award.
    #     number_hunters: integer, number of times players chose to hunt in the last round.

    pass